package com.eb.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.eb.context.BaseContext;
import com.eb.domain.*;
import com.eb.dto.AddInnovationDto;
import com.eb.dto.EditInnovationDto;
import com.eb.dto.InnovationListDto;
import com.eb.mapper.*;
import com.eb.result.PageResult;
import com.eb.service.InnovationService;
import com.eb.service.LookService;
import com.eb.utils.InnovationUtil;
import com.eb.vo.CommentVo;
import com.eb.vo.InnovationDetailVo;
import com.eb.vo.RankInnovationVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import com.eb.domain.Innovation;
import com.eb.domain.Likes;
import com.eb.exception.BaseException;
import com.eb.mapper.IInnovationMapper;
import com.eb.mapper.ILikesMapper;
import com.eb.mapper.IUserMapper;
import com.eb.service.LikesService;
import com.eb.vo.InnovationVO;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class InnovationServiceImpl extends ServiceImpl<IInnovationMapper, Innovation>
        implements InnovationService {

    @Autowired
    private IRegionMapper iRegionMapper;
    @Autowired
    private ILikesMapper iLikeMapper;
    @Autowired
    private ICommentMapper iCommentMapper;
    @Autowired
    private ILookMapper iLookMapper;
    @Autowired
    private IPreserveMapper iPreserveMapper;
    @Autowired
    private IUserMapper iUserMapper;
    @Autowired
    private LikesService likesService;
    @Autowired
    private LookService lookService;
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public boolean createInnovation(AddInnovationDto addInnovationDto) {

        //空值异常
        if (addInnovationDto.getTitle() == null)
        {
            throw new BaseException("标题不能为空");
        }else if (addInnovationDto.getContent() == null)
        {
            throw new BaseException("内容不能为空");
        }

        //复制属性
        Innovation innovation = BeanUtil.copyProperties(addInnovationDto, Innovation.class);
        innovation.setUserId(BaseContext.getCurrentId());
        innovation.setCreateTime(LocalDateTime.now());
        innovation.setUpdateTime(LocalDateTime.now());
        innovation.setStatus(1);
        //TODO 保存图片列表
        //保存到数据库
        save(innovation);
        return true;
    }

    @Override
    @Transactional
    public InnovationDetailVo selectInnovationDetails(Integer innovationId) {
        InnovationDetailVo detailVo = new InnovationDetailVo();
        //查询基础信息
        Innovation innovation = getById(innovationId);
        //TODO 管理员禁用后无法查看查看状态是否被禁用
        if (innovation.getStatus() != 1)
        {
            Innovation innovation1 = InnovationUtil.BanInnovation(innovation);
            BeanUtil.copyProperties(innovation,detailVo);
            return detailVo;
        }
        //TODO 浏览记录写入Redis消息队列
        lookService.addLook(innovationId);

        //拷贝基本信息
        BeanUtil.copyProperties(innovation,detailVo);
        //发帖人名称
        User user1 = iUserMapper.selectById(innovation.getUserId());
        detailVo.setUserNickname(user1.getNickname());
        //区域名称
        Region region = iRegionMapper.selectById(innovation.getRegionId());
        detailVo.setRegionName(region.getName());
        //点赞量
        Long likenum = iLikeMapper.selectCount(
                new QueryWrapper<Likes>().eq("innovation_id",innovationId)
        );
        detailVo.setLikenum(likenum);
        //评论量
        Long comment = iCommentMapper.selectCount(
                new QueryWrapper<Comment>().eq("innovation_id",innovationId)
        );
        detailVo.setCommentnum(comment);
        //收藏量
        Long preserve = iPreserveMapper.selectCount(
                new QueryWrapper<Preserve>().eq("innovation_id",innovationId)
        );
        detailVo.setPreservenum(preserve);
        //浏览量
        Long look = iLookMapper.selectCount(
                new QueryWrapper<Look>().eq("innovation_id",innovationId)
        );
        detailVo.setLooknum(look);

        //TODO 图片列表

        //评论列表
        //定义返回值列表
        List<CommentVo> commentVos = new ArrayList<>();
        List<Comment> comments = iCommentMapper.selectList(
                new QueryWrapper<Comment>().eq("innovation_id", innovationId)
        );
        //遍历评论列表重新封装
        for(Comment comment1: comments)
        {
            CommentVo commentVo = new CommentVo();
            //复制常规属性
            BeanUtil.copyProperties(comment1,commentVo);
            Integer userId = comment1.getUserId();
            User user = iUserMapper.selectById(userId);
            //昵称和头像
            commentVo.setUserNickName(user.getNickname());
            commentVo.setImage(user.getImage());
            //添加后封装
            commentVos.add(commentVo);
        }
        detailVo.setCommentVos(commentVos);
        return detailVo;
    }

    @Override
    public PageResult selectInnovationVoList(InnovationListDto innovationListDto) {
        QueryWrapper<Innovation> wrapper = new QueryWrapper<>();
        Long pageNum = innovationListDto.getPageNum();
        Long pageSize = innovationListDto.getPageSize();

        //条件查询
        if (innovationListDto.getTitle() != null)
        wrapper.like("title",innovationListDto.getTitle());

        if (innovationListDto.getRegionId() != null)
        wrapper.eq("region_id",innovationListDto.getRegionId());
        //状态只能是1
        wrapper.eq("status",1);
        Page<Innovation> page = Page.of(pageNum, pageSize);
        Page<Innovation> innovationPage = page(page, wrapper);
        //获取数据后再封装
        List<Innovation> records = innovationPage.getRecords();
        List<InnovationVO> innovationVos = new ArrayList<>();
        for(Innovation innovation:records)
        {
            InnovationVO innovationVo = new InnovationVO();
            //基本信息拷贝
            BeanUtil.copyProperties(innovation,innovationVo);
            //内容只获取前20个字符
            if (innovationVo.getContent().length()>20)
            innovationVo.setContent(innovationVo.getContent().substring(0,20));
            //获取用户名
            Integer userId = innovation.getUserId();
            User user = iUserMapper.selectById(userId);
            innovationVo.setNickName(user.getNickname());
            //获取点赞数
            Long likenum = iLikeMapper.selectCount(
                    new QueryWrapper<Likes>().eq("innovation_id", innovation.getId())
            );
            innovationVo.setLike(likenum);
            innovationVos.add(innovationVo);
        }
        PageResult pageResult = new PageResult();
        pageResult.setRecords(innovationVos);
        pageResult.setTotal(innovationVos.size());

        return pageResult;
    }

    @Override
    public boolean updateInnovation(EditInnovationDto editInnovationDto) {
        //复制属性
        Innovation innovation = BeanUtil.copyProperties(editInnovationDto, Innovation.class);
        innovation.setUserId(BaseContext.getCurrentId());
        innovation.setUpdateTime(LocalDateTime.now());
        innovation.setStatus(1);
        //TODO 保存图片列表
        //保存到数据库
        saveOrUpdate(innovation);
        return true;
    }

    /**
     * 根据用户id获取用户发表的帖子列表
     * @param userId
     * @return
     */
    @Override
    public List<InnovationVO> getInnovationByUserId(Integer userId) {
        //创建一个List<InnovationVO>对象用来存储查到的帖子
        List<InnovationVO> List = new ArrayList<>();
        //创建QueryWrapper对象构建查询条件
        QueryWrapper<Innovation> wrapper = new QueryWrapper<>();
        //添加查询条件
        wrapper.eq("user_id",userId);

        //查询innovation表中的帖子id、标题、内容、帖子标签、分区id、发帖人id
        List<Innovation> innovationList = baseMapper.selectList(wrapper);

        //如果innovationList为空，抛出异常返回前端
        if (innovationList == null) {
            throw new BaseException("用户id为：" + userId + "的用户没有发表过帖子");
        }

        //如果content为空，抛出异常
        for (Innovation innovation : innovationList) {
            if (innovation.getContent() == null) {
                throw new BaseException("帖子内容不能为空");
            }
        }

        //将内容切割成20个字符
        for (Innovation innovation : innovationList) {
            String content = innovation.getContent();
            if (content.length() > 20) {
                content = content.substring(0, 20) + "...";
            }
            innovation.setContent(content);
        }


        //遍历innovationList
        for (Innovation innovation : innovationList) {

//            //创建QueryWrapper对象构建查询条件
//            QueryWrapper<Likes> wrapper1 = new QueryWrapper<>();
//            //添加查询条件
//            wrapper1.eq("innovation_id",innovation.getId());
//            //统计帖子的点赞数
            Long count = likesService.countLikesByInnovationId(innovation.getId());


            //创建InnovationVO对象
            InnovationVO innovationVO = new InnovationVO();
            //将innovationList中的数据赋值给InnovationVO对象
            BeanUtil.copyProperties(innovation,innovationVO);


            //将点赞数赋值给InnovationVO对象
            innovationVO.setLike(count);

            //将用户姓名赋值给InnovationVO对象
            Integer userId1 = innovation.getUserId();
            String username = iUserMapper.selectById(userId1).getNickname();
            innovationVO.setNickName(username);

            //将InnovationVO对象添加到List中
            List.add(innovationVO);
        }
        return List;
    }

    @Override
    public List<RankInnovationVO> getRank() {
        //从redis中获取排行信息
        Set<String> range = redisTemplate.opsForZSet().reverseRange("innovation.rank", 0, 9);
        List<String> top10 = range.stream().collect(Collectors.toList());
        List<RankInnovationVO> rankInnovationVOS = new ArrayList<>();
        for (String code : top10)
        {
            RankInnovationVO rankInnovationVO = new RankInnovationVO();
            //处理字符串，拿出帖子id
            String[] msg = code.split(":");
            Integer innoId = Integer.valueOf(msg[2]);
            Innovation innovation = getById(innoId);
            //获取信息封装到VO
            rankInnovationVO.setId(innoId);
            rankInnovationVO.setTitle(innovation.getTitle());
            User user = iUserMapper.selectById(innovation.getUserId());
            rankInnovationVO.setNickName(user.getNickname());
            Region region = iRegionMapper.selectById(innovation.getRegionId());
            rankInnovationVO.setRegionName(region.getName());
            rankInnovationVOS.add(rankInnovationVO);
        }


        return rankInnovationVOS;
    }
}
